home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
HFTUBE.ZIP
/
TUBE.ASM
< prev
next >
Wrap
Assembly Source File
|
1995-05-06
|
18KB
|
304 lines
CodeTube Segment Para Use16
Assume Cs:CodeTube
Public VoxelTubeInit,VoxelTubeFree
Public VoxelTube,DrawVoxelTube
; ===========================================================================
; Initialize voxel tube
; /////////////////////
; description: Allocate memory and calculate required tables for voxel tube
; routine. Use procedure VoxelTubeFree for releasing allocated
; memory units.
; input: Nothing
; returns: CF is set if not enough memory, else Ax=output segment
; ===========================================================================
VoxelTubeInit Proc Far
.386
Mov Ah,48h
Mov Bx,23A0h ; Amount of memory required
Int 21h
Jc NotEnoughMemory
Mov Cs:[OutputSeg],Ax
Add Ax,1000h ; Output segment size in paragraphs
Mov Cs:[PixelPointerSeg],Ax
Add Ax,0FA0h ; Pixel pointer table size
Mov Cs:[ProjectTableseg],Ax
Mov Es,Ax
; By setting limit values in formula
; e=zl·yl'/(a·yl-yl')
; we get eye distance from projection plane which will be placed in formula
; y'=a·e·y/(z+e)
; which can be used to calculate all projected columns
; Below are exlanations for used parameters:
; e eye distance from projection plane (0.06477)
; zl a edge distance of the column from projection plane (62)
; yl a edge height of the column (255)
; yl' a edge projected height of the column at specified distance (33)
; a the projected height of 1 unit height column at distance 0 (126)
; y' projected value of specified column
; y height of the column
; z distance of the column from the plane
zl Equ 62
yl Equ 255
ylp Equ 33
a Equ 126
e Equ zl*ylp/(a*yl-ylp)
Mov Bx,3E00h
; Mov Ecx,e*00010000h+003E0000h
Mov Ecx,2510+003E0000h
ProjectTableLoop2: Mov Esi,318882
ProjectTableLoop1: Mov Eax,Esi
Xor Edx,Edx
Div Ecx
Add Dx,Dx
Adc Ax,01h
Cmp Ax,0080h
Jb NoRadiusFix
Mov Al,7Fh
NoRadiusFix: Mov Es:[Bx],Al
; Add Esi,a*e*00010000h
Add Esi,318882
Inc Bl
Jnz ProjectTableLoop1
Mov Byte Ptr Es:[Bx],Bl
Sub Ecx,00010000h
Dec Bh
Jns ProjectTableLoop2
Mov Bx,3F00h
ProjectTableLoop3: Mov Byte Ptr Es:[Bx],00h
Inc Bl
Jnz ProjectTableLoop3
; Mov Bx,3E00h
; Mov Ecx,003E21E4h
; ProjectTableLoop2: Xor Esi,Esi
; ProjectTableLoop1: Xor Edx,Edx
; Mov Eax,Esi
; Div Ecx
; Inc Ax
; Cmp Ax,0080h
; Jb NoRadiusFix
; Mov Al,7Fh
; NoRadiusFix: Mov Es:[Bx],Al
; Add Esi,00059AA6h
; Inc Bl
; Jnz ProjectTableLoop1
; Sub Ecx,00010000h
; Dec Bh
; Jns ProjectTableLoop2
; Mov Bx,3F00h
; ProjectTableLoop3: Mov Byte Ptr Es:[Bx],00h
; Inc Bl
; Jnz ProjectTableLoop3
Mov Ax,Cs:[OutputSeg]
Clc
NotEnoughMemory: RetF
VoxelTubeInit EndP
; ===========================================================================
; Release Voxel tube
; //////////////////
; description: Free allocater memory units for voxel tube
; input: Nothing
; returns: CF is set if can't release memory
; ===========================================================================
VoxelTubeFree Proc Far
Mov Ah,49h
Mov Es,Cs:[OutputSeg]
Int 21h
RetF
VoxelTubeFree EndP
; ===========================================================================
; Calculate voxel tube
; ////////////////////
; description: Draw voxel tube bitmap to the output segment by using radius
; and color table. Use procedure DrawVoxelTube to draw bitmap
; right on the screen.
; input: Ds=segment to wall radiuses (table size 512x128)
; Gs=segment to wall colors (table size 512x128)
; Dx=tube rotate value (0-511)
; returns: Nothing
; ===========================================================================
VoxelTube Proc Far
.386
Mov Ax,Cs:[OutputSeg] ; Move output segment to Es
Mov Es,Ax
Mov Ax,Cs:[ProjectTableSeg] ; Move project table -segment to Fs
Mov Fs,Ax
Mov Bp,01FFh ; Line counter
RowChange: Mov Si,Bp ; Move read line number to Si
Sub Si,Dx
Jnc NoOverflow
Add Si,0200h
NoOverflow: Xor Bh,Bh ; Start distance
Mov Ah,Cs:[Bp+LineStart] ; Maximum radius
Mov Di,Bp ; Output line
MoveRayLoop: Mov Bl,[Si] ; Read radius
Mov Al,Fs:[Bx] ; Project radius
Sub Al,Ah ; Test if projected radius is shortest by now
Jc DrawLine2
DrawRet2: Mov Bl,[Si+0200h] ; Read next radius
Add Si,0400h ; Move ray position
Mov Al,Fs:[Bx+0100h] ; Projected radius
Add Bh,02h ; Increase distance
Sub Al,Ah ; Test if projected radius is shortest by now
Jnc MoveRayLoop
DrawLine1: Add Ah,Al ; Move new projected radius to Ah
Jz RowEnd ; If projected radius is 128, move to next row
Mov Cl,Gs:[Si-0200h] ; Take wall color
Sub Cl,Bh ; Decrease distance color from wall color
DrawLineLoop1: Mov Es:[Di],Cl ; Draw as many pixels as is the difference
Add Di,0200h ; between new and old projected radius
Inc Al
Jnz DrawLineLoop1
Jmp MoveRayLoop ; Back to the ray loop
DrawLine2: Add Ah,Al ; ... see above
Jz RowEnd
Mov Cl,Gs:[Si]
Sub Cl,Bh
DrawLineLoop2: Mov Es:[Di],Cl
Add Di,0200h
Inc Al
Jnz DrawLineLoop2
Jmp DrawRet2
RowEnd: Dec Bp ; Next row
Jns RowChange ; If no more, exit
RetF
ProjectTableSeg Dw ?
OutputSeg Dw ?
LineStart Db 06Ch,06Ch,06Ch,06Ch,06Ch,06Ch,06Ch,06Ch
Db 06Dh,06Dh,06Dh,06Dh,06Dh,06Dh,06Eh,06Eh
Db 06Eh,06Eh,06Fh,06Fh,06Fh,070h,070h,070h
Db 071h,071h,072h,072h,073h,073h,074h,074h
Db 075h,076h,076h,077h,078h,078h,079h,07Ah
Db 07Bh,07Bh,07Ch,07Dh,07Eh,07Fh,07Dh,07Ah
Db 078h,076h,074h,072h,070h,06Eh,06Dh,06Bh
Db 069h,068h,066h,065h,064h,062h,061h,060h
Db 05Fh,05Dh,05Ch,05Bh,05Bh,059h,058h,057h
Db 057h,056h,055h,054h,053h,053h,052h,051h
Db 051h,050h,050h,04Fh,04Eh,04Eh,04Dh,04Dh
Db 04Ch,04Ch,04Bh,04Bh,04Ah,04Ah,04Ah,049h
Db 049h,049h,048h,048h,047h,047h,047h,047h
Db 046h,046h,046h,046h,046h,045h,045h,045h
Db 045h,045h,044h,044h,044h,044h,044h,044h
Db 044h,044h,044h,044h,044h,044h,044h,044h
Db 044h,044h,044h,044h,044h,044h,044h,044h
Db 044h,044h,044h,044h,044h,044h,045h,045h
Db 045h,045h,045h,046h,046h,046h,046h,046h
Db 047h,047h,047h,047h,048h,048h,049h,049h
Db 049h,04Ah,04Ah,04Ah,04Bh,04Bh,04Ch,04Ch
Db 04Dh,04Dh,04Eh,04Eh,04Fh,050h,050h,051h
Db 051h,052h,053h,053h,054h,055h,056h,057h
Db 057h,058h,059h,05Bh,05Bh,05Ch,05Dh,05Fh
Db 060h,061h,062h,064h,065h,066h,068h,069h
Db 06Bh,06Dh,06Eh,070h,072h,074h,076h,078h
Db 07Ah,07Dh,07Fh,07Eh,07Dh,07Ch,07Bh,07Bh
Db 07Ah,079h,078h,078h,077h,076h,076h,075h
Db 074h,074h,073h,073h,072h,072h,071h,071h
Db 070h,070h,070h,06Fh,06Fh,06Fh,06Eh,06Eh
Db 06Eh,06Eh,06Dh,06Dh,06Dh,06Dh,06Dh,06Dh
Db 06Ch,06Ch,06Ch,06Ch,06Ch,06Ch,06Ch,06Ch
Db 06Ch,06Ch,06Ch,06Ch,06Ch,06Ch,06Ch,06Ch
Db 06Dh,06Dh,06Dh,06Dh,06Dh,06Dh,06Eh,06Eh
Db 06Eh,06Eh,06Fh,06Fh,06Fh,070h,070h,070h
Db 071h,071h,072h,072h,073h,073h,074h,074h
Db 075h,076h,076h,077h,078h,078h,079h,07Ah
Db 07Bh,07Bh,07Ch,07Dh,07Eh,07Fh,07Dh,07Ah
Db 078h,076h,074h,072h,070h,06Eh,06Dh,06Bh
Db 069h,068h,066h,065h,064h,062h,061h,060h
Db 05Fh,05Dh,05Ch,05Bh,05Bh,059h,058h,057h
Db 057h,056h,055h,054h,053h,053h,052h,051h
Db 051h,050h,050h,04Fh,04Eh,04Eh,04Dh,04Dh
Db 04Ch,04Ch,04Bh,04Bh,04Ah,04Ah,04Ah,049h
Db 049h,049h,048h,048h,047h,047h,047h,047h
Db 046h,046h,046h,046h,046h,045h,045h,045h
Db 045h,045h,044h,044h,044h,044h,044h,044h
Db 044h,044h,044h,044h,044h,044h,044h,044h
Db 044h,044h,044h,044h,044h,044h,044h,044h
Db 044h,044h,044h,044h,044h,044h,045h,045h
Db 045h,045h,045h,046h,046h,046h,046h,046h
Db 047h,047h,047h,047h,048h,048h,049h,049h
Db 049h,04Ah,04Ah,04Ah,04Bh,04Bh,04Ch,04Ch
Db 04Dh,04Dh,04Eh,04Eh,04Fh,050h,050h,051h
Db 051h,052h,053h,053h,054h,055h,056h,057h
Db 057h,058h,059h,05Bh,05Bh,05Ch,05Dh,05Fh
Db 060h,061h,062h,064h,065h,066h,068h,069h
Db 06Bh,06Dh,06Eh,070h,072h,074h,076h,078h
Db 07Ah,07Dh,07Fh,07Eh,07Dh,07Ch,07Bh,07Bh
Db 07Ah,079h,078h,078h,077h,076h,076h,075h
Db 074h,074h,073h,073h,072h,072h,071h,071h
Db 070h,070h,070h,06Fh,06Fh,06Fh,06Eh,06Eh
Db 06Eh,06Eh,06Dh,06Dh,06Dh,06Dh,06Dh,06Dh
Db 06Ch,06Ch,06Ch,06Ch,06Ch,06Ch,06Ch,06Ch
VoxelTube EndP
; ===========================================================================
; Draw calculated tube to the screen
; //////////////////////////////////
; description: Draw voxel tube bitmap which is calculated to the memory on
; the screen in the shape of circle.
; input: Es=video segment (320x200x256)
; returns: Nothing
; ===========================================================================
DrawVoxelTube Proc Far
.486
Push Ds
Mov Ax,Cs:[OutputSeg] ; Read data from output segment
Mov Fs,Ax ; and store it to video segment
Mov Ax,Cs:[PixelPointerSeg] ; via pixel read pointers
Mov Ds,Ax
Mov Bp,0F9FEh
Mov Bx,0FFFCh
Mov Di,0FA00h
DrawTubeLoop: Mov Si,Ds:[Bp] ; Read a read position
Add Bx,04h ; Increase output pointer A
Mov Al,Fs:[Si] ; Read data A from read position
Mov Dl,Fs:[Si+0100h] ; Read data B from the opposite position of the tube
Mov Si,Ds:[Bp-02h] ; Read another read position
Sub Di,04h ; Decrease output pointer B
Mov Ah,Fs:[Si] ; Read data A...
Mov Dh,Fs:[Si+0100h]
Mov Si,Ds:[Bp-04h]
Bswap Eax ; Prepare higher bytes for modification
BSwap Edx
Mov Ah,Fs:[Si]
Mov Dh,Fs:[Si+0100h]
Mov Si,Ds:[Bp-06h]
Mov Dl,Fs:[Si+0100h]
Mov Es:[Di],Edx ; Output data B to output pointer B
Sub Bp,08h ; Decrease table pointer
Mov Al,Fs:[Si]
Bswap Eax ; Order data A for output
Mov Es:[Bx],Eax ; Output data A to output pointer A
Jnc DrawTubeLoop ; If all screen copied, exit
Pop Ds
RetF
PixelPointerSeg Dw ?
DrawVoxelTube EndP
CodeTube EndS